#include "stdafx.h"
#include <CppUnitTest.h>

#include "nef.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace nef;

class Valty
{ 
public:
	typedef std::shared_ptr<Valty> Ptr;
};

class Client
{
public:
	typedef std::shared_ptr<Client> Ptr;

	Valty::Ptr V;
};

template<>
struct nef_traits<Client>
{
	typedef nef_import<Client, Valty, &Client::V, NO_CONTRACT, false> import0;
};

class Server
{
public:
	Client::Ptr C;
};

template<>
struct nef_traits<Server>
{
	typedef nef_import<Server, Client, &Server::C, NO_CONTRACT, false> import0;
};

namespace nef_unit_test
{
	nef_export<Valty> valty_export;
	nef_export<Client> client_export;
	nef_export<Server> server_export;

	TEST_CLASS(auto_import_tests)
	{
	public:
		TEST_METHOD(Auto_Single_Dep)
		{
			auto cat = Catalog::Create();

			auto client = cat->GetExportedValue<Client>(NO_CONTRACT, false);

			Assert::IsNotNull(client.get(), L"Could not find exported client", LINE_INFO());

			Assert::IsNotNull(client->V.get(), L"Could not find the exported val", LINE_INFO());
		}

		TEST_METHOD(Auto_Two_Level)
		{
			auto cat = Catalog::Create();

			try
			{
				auto server = cat->GetExportedValue<Server>(NO_CONTRACT, true);

				Assert::IsNotNull(server.get(), L"Could not find exported server", LINE_INFO());
				Assert::IsNotNull(server->C.get(), L"Could not find the exported client", LINE_INFO());
				Assert::IsNotNull(server->C->V.get(), L"Could not find the exported val", LINE_INFO());
			}
			catch (std::exception &ex)
			{
				std::string s = ex.what();

				std::wstring ws(s.begin(), s.end());

				Assert::Fail(ws.c_str(), LINE_INFO());
			}

			
		}
	};
}